package gov.dhs.cis.soa.readers;

import gov.dhs.cis.soa.SOAData;
import gov.dhs.cis.soa.Utils;
import gov.dhs.cis.soa.data.Actor;
import gov.dhs.cis.soa.data.EntitiesReferences;
import gov.dhs.cis.soa.data.UseCase;

import java.util.ArrayList;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


public class UseCasesReader extends ExcelReader {
	static final Logger loger = Logger.getLogger(UseCasesReader.class);

	private final String EXT_USECASES_FILE_NAME = "Use Case Inventory 5-21-10-Master.xls";
	
	//String SHEET_NAME = "Inventory - Master";	//"Use Case Inventory";	//"B3 (Interim)";
	String[] UC_SHEET_NAMES = { "UC Inventory - Master", "Service Inventory" };
	//String[] UC_TYPES = { "UC", "SD" };
	
	private String MOD_SINCE_IRR_COL_NUM = "C";
	private String USECASE_NUM_COL_NUM = "D";
	private String NAME_COL_NUM = "E";
	private String STATUS_COL_NUM = "G";
	private String DESC_COL_NUM = "J";
	private String WIPT_COL_NUM = "K";
	private String STEREO_COL_NUM = "L";
	private String BUS_PROC_COL_NUM = "N";
	private String REL_COL_NUM = "O";
	private String ACTOR_COL_NUM = "P";
	
	private int MAX_PROCS = 160;
		
	public SOAData extractUseCases(SOAData soaData) {
		loger.debug("Extracting UseCases layer Sheet...");
		HSSFWorkbook w = openFile(EXT_USECASES_FILE_NAME);
		ArrayList<UseCase> useCaseList = new ArrayList<UseCase>();
		soaData.useCaseList = useCaseList;

		for(int sheetNum = 0; sheetNum < UC_SHEET_NAMES.length; sheetNum++) {
			String sheetName = UC_SHEET_NAMES[sheetNum];
			HSSFSheet s1 = w.getSheet(sheetName);
			int rows = s1.getLastRowNum();
			loger.debug("S1 rows =" + rows);
			
			for (int n = 2; n < MAX_PROCS; n++) {
				HSSFRow row = s1.getRow(n);
				if(row == null)
					continue;
				String name = getCellStringValue(w, row, NAME_COL_NUM);
				if(Utils.isEmpty(name)) {
					loger.warn(sheetName + ": UseCase Name is Null/Empty at row : " + n + ", ignoring this row.");
					continue;
				}
				String number = getCellStringValue(w, row, USECASE_NUM_COL_NUM);
				String modSinceIRR = getCellStringValue(w, row, MOD_SINCE_IRR_COL_NUM);
				if (!Utils.isEmpty(modSinceIRR) && modSinceIRR.startsWith("Delete")) {
					loger.warn(sheetName + ": Usescase [" + name + " - " + number + "] at <" + n + "> is marked for Delete. Skipping the use case.");
					continue;
				}
				String status = getCellStringValue(w, row, STATUS_COL_NUM);
				if (!Utils.isEmpty(status) && "Obsolete".equalsIgnoreCase(status)/* || "Not for Increment 1".equalsIgnoreCase(status)*/ ||
						"Not yet reviewed".equalsIgnoreCase(status)) {
					loger.warn(sheetName + ": Usescase [" + name + " - " + number + "] at <" + n + "> is Empty/Null/Obsolete. Skipping the use case.");
					continue;
				}
				String desc = getCellStringValue(w, row, DESC_COL_NUM);
				String wipt = getCellStringValue(w, row, WIPT_COL_NUM);
				String stereotype = getCellStringValue(w, row, STEREO_COL_NUM);
				String busProcName = getCellStringValue(w, row, BUS_PROC_COL_NUM);
				String rel = getCellStringValue(w, row, REL_COL_NUM);
				String actors = getCellStringValue(w, row, ACTOR_COL_NUM);
				
				UseCase usecase = new UseCase();
				usecase.id = Utils.getNextId();
				usecase.unumber = number;
				usecase.status = status;
				usecase.modSiceIRR = modSinceIRR;
				usecase.uname = name.replaceAll("\\n", ",");;
				usecase.wipt = wipt;
				usecase.stereotype = stereotype;
				usecase.busProcessName = busProcName;
				usecase.descText = desc;
				usecase.release = Utils.convert2Release(rel);
				
				usecase.createDescription();
				
				if("N/A".equalsIgnoreCase(actors))
					actors = "";
				actors = actors.replaceAll("\\n", ",");
				String[] acts = actors.split(",");
				if(acts != null && acts.length > 0) {
					for (int i = 0; i < acts.length; i++) {
						String pActorName = acts[i].replaceAll("\\?", " ").trim();
						if(Utils.isEmpty(pActorName))
							continue;
						Actor a = Utils.findActorByName(pActorName, soaData.actorList);
						if(a == null) {
							loger.error("Couldn't find Actor for UseCase: <" + usecase.uname + "> and Actor:<" + pActorName + ">");
							continue;
						}
						//usecase.addReferedActor(a);
						soaData.addEntitiesReferences(EntitiesReferences.getNewEntitiesReference(usecase, a, null));
					}
				}
				
				useCaseList.add(usecase);
			}
		}
		closeAll(w);
		return soaData;
	}
}
